package com.av.client.panels;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Enumeration;

import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JSeparator;

import com.av.client.AvDesktop;
import com.av.client.frames.AbonoFrame;
import com.av.client.frames.AdeudoFrame;
import com.av.client.frames.ElementoCatalogoFrame;
import com.av.client.frames.EntradaSalidaFrame;
import com.av.client.frames.LoginFrame;
import com.av.client.frames.TarjetaFrame;
import com.av.client.frames.UsuarioFrame;
import com.av.client.util.idioma.Etiqueta;
import com.av.client.util.idioma.ManejadorIdiomas;
import com.av.client.util.idioma.ManejadorIdiomas.IdiomaEvent;
import com.av.client.util.idioma.ManejadorIdiomas.IdiomaEventListener;
import com.av.client.util.sesion.AdministradorSesion;
import com.av.client.util.sesion.AdministradorSesion.SesionEvent;
import com.av.client.util.sesion.AdministradorSesion.SesionEventListener;
import com.av.client.util.sesion.SesionCreador.Sesion;
import com.av.db.dataobjects.Idioma;
import com.av.db.dataobjects.enums.Rol;

@SuppressWarnings("serial")
public class MainMenuPanel extends JPanel {

	private JMenuBar mnbDesktop;

	private JMenu mnuArchivo;
	private JMenuItem mniLogin;
	private JMenuItem mniSalir;

	private JMenu mnuEntrada;
	private JMenuItem mniEntradaSalida;

	private JMenu mnuAdministracion;
	private JMenuItem mniUsuario;
	private JMenuItem mniTarjeta;
	private JMenuItem mniCatalogos;

	private JMenu mnuEdoCta;
	private JMenuItem mniAdeudo;
	private JMenuItem mniAbono;

	private JMenu mnuPreferencias;
	private JMenuItem mniAcercaDe;
	private JMenu mnuIdioma;
	private ButtonGroup grupoIdiomas = new ButtonGroup();

	private MenuItemHandler miHandler = new MenuItemHandler();
	private ManejadorIdiomas mi;
	private AdministradorSesion as;

	public MainMenuPanel() {
		super();
		mi = ManejadorIdiomas.getInstance();
		as = AdministradorSesion.getInstance();
		initComponents();
		addListeners();
	}// MainMenuPanel

	private void addListeners() {
		mi.addIdiomaEventListener(new IdiomaEventListener() {
			@Override
			public void changedIdiomaEvent(IdiomaEvent evt) {
				setLabels();

				Idioma seleccionado;
				JRadioButtonMenuItem i;
				Enumeration<AbstractButton> tmp;
				if (evt.getSource() instanceof Idioma) {
					seleccionado = (Idioma) evt.getSource();
					tmp = grupoIdiomas.getElements();
					while (tmp.hasMoreElements()) {
						i = (JRadioButtonMenuItem) tmp.nextElement();
						i.setSelected(i.getText().equals(
								seleccionado.getDescripcion()));
					}
				}
			}
		});

		as.addSesionEventListener(new SesionEventListener() {
			@Override
			public void changedSesionEvent(SesionEvent evt) {
				if (evt.getSource() instanceof Sesion) {
					Sesion sesion = (Sesion) evt.getSource();
					if (sesion.getUsuario() != null
							&& sesion.getUsuario().getRol() != null) {
						cargarPermisos(sesion.getUsuario().getRol());
					}
					mniLogin.setText(mi
							.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_LOGOUT));
				}
			}
		});
	}// addListeners

	/**
	 * Funcion que restablece las etiquetas para todos los componentes
	 */
	private void setLabels() {
		mnuArchivo.setText(mi.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNU_ARCHIVO));
		if (as.getSesionActiva() != null) {
			mniLogin
					.setText(mi.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_LOGOUT));
		} else {
			mniLogin.setText(mi.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_LOGIN));
		}
		mniSalir.setText(mi.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_SALIR));
		mnuEntrada.setText(mi.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNU_ENTRADA));
		mniEntradaSalida.setText(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_ENTRADA_SALIDA));
		mnuAdministracion.setText(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNU_ADMINISTRACION));
		mniUsuario.setText(mi.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_USUARIO));
		mniTarjeta.setText(mi.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_TARJETA));
		mniCatalogos.setText(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_CATALOGOS));
		mnuEdoCta.setText(mi.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNU_EDOCTA));
		mniAdeudo.setText(mi.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_ADEUDOS));
		mniAbono.setText(mi.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_ABONOS));
		mnuPreferencias.setText(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNU_PREFERENCIAS));
		mniAcercaDe.setText(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_ACERCA_DE));
		mnuIdioma.setText(mi.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_IDIOMA));
	}// setLabels

	/**
	 * Asigna los permisos correspondientes a la session asignada
	 */
	private void cargarPermisos(Rol rol) {
		switch (rol) {
		case ADMIN:
			mnuAdministracion.setVisible(true);
			mnuAdministracion.setEnabled(true);
			mniUsuario.setVisible(true);
			mniUsuario.setEnabled(true);
			mniTarjeta.setVisible(true);
			mniTarjeta.setEnabled(true);
			mniCatalogos.setVisible(true);
			mniCatalogos.setEnabled(true);
			mnuEdoCta.setVisible(true);
			mnuEdoCta.setEnabled(true);
			mniAdeudo.setVisible(true);
			mniAdeudo.setEnabled(true);
			mniAbono.setVisible(true);
			mniAbono.setEnabled(true);
			mnuEntrada.setVisible(true);
			mnuEntrada.setEnabled(true);
			mniEntradaSalida.setVisible(true);
			mniEntradaSalida.setEnabled(true);
			break;
		case CONDU:
			mnuAdministracion.setVisible(false);
			mnuAdministracion.setEnabled(false);
			mniUsuario.setVisible(false);
			mniUsuario.setEnabled(false);
			mniTarjeta.setVisible(false);
			mniTarjeta.setEnabled(false);
			mniCatalogos.setVisible(false);
			mniCatalogos.setEnabled(false);
			mnuEdoCta.setVisible(true);
			mnuEdoCta.setEnabled(true);
			mniAdeudo.setVisible(true);
			mniAdeudo.setEnabled(true);
			mniAbono.setVisible(true);
			mniAbono.setEnabled(true);
			mnuEntrada.setVisible(true);
			mnuEntrada.setEnabled(true);
			mniEntradaSalida.setVisible(true);
			mniEntradaSalida.setEnabled(true);
			break;
		case GUARD:
			mnuAdministracion.setVisible(true);
			mnuAdministracion.setEnabled(true);
			mniUsuario.setVisible(true);
			mniUsuario.setEnabled(false);
			mniTarjeta.setVisible(true);
			mniTarjeta.setEnabled(false);
			mniCatalogos.setVisible(true);
			mniCatalogos.setEnabled(false);
			mnuEdoCta.setVisible(true);
			mnuEdoCta.setEnabled(true);
			mniAdeudo.setVisible(true);
			mniAdeudo.setEnabled(true);
			mniAbono.setVisible(true);
			mniAbono.setEnabled(true);
			mnuEntrada.setVisible(true);
			mnuEntrada.setEnabled(true);
			mniEntradaSalida.setVisible(true);
			mniEntradaSalida.setEnabled(false);
			break;
		case USUAR:
			mnuAdministracion.setVisible(true);
			mnuAdministracion.setEnabled(true);
			mniUsuario.setVisible(true);
			mniUsuario.setEnabled(false);
			mniTarjeta.setVisible(true);
			mniTarjeta.setEnabled(false);
			mniCatalogos.setVisible(true);
			mniCatalogos.setEnabled(false);
			mnuEdoCta.setVisible(true);
			mnuEdoCta.setEnabled(true);
			mniAdeudo.setVisible(true);
			mniAdeudo.setEnabled(true);
			mniAbono.setVisible(true);
			mniAbono.setEnabled(true);
			mnuEntrada.setVisible(true);
			mnuEntrada.setEnabled(true);
			mniEntradaSalida.setVisible(true);
			mniEntradaSalida.setEnabled(false);
			break;
		case DEFAULT:
			mnuAdministracion.setVisible(false);
			mnuAdministracion.setEnabled(false);
			mniUsuario.setVisible(false);
			mniUsuario.setEnabled(false);
			mniTarjeta.setVisible(false);
			mniTarjeta.setEnabled(false);
			mniCatalogos.setVisible(false);
			mniCatalogos.setEnabled(false);
			mnuEdoCta.setVisible(false);
			mnuEdoCta.setEnabled(false);
			mniAdeudo.setVisible(false);
			mniAdeudo.setEnabled(false);
			mniAbono.setVisible(false);
			mniAbono.setEnabled(false);
			mnuEntrada.setVisible(false);
			mnuEntrada.setEnabled(false);
			mniEntradaSalida.setVisible(false);
			mniEntradaSalida.setEnabled(false);
			break;
		}
	}// setPermissions

	private void initComponents() {
		setLayout(new FlowLayout());
		ManejadorIdiomas mi = ManejadorIdiomas.getInstance();

		mnbDesktop = new JMenuBar();
		mnbDesktop.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));

		// Archivo

		mnuArchivo = new JMenu(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNU_ARCHIVO));
		mnbDesktop.add(mnuArchivo);

		mniLogin = new JMenuItem(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_LOGIN), KeyEvent.VK_I);
		mniLogin.addActionListener(miHandler);
		mnuArchivo.add(mniLogin);

		mnuArchivo.add(new JSeparator());

		mniSalir = new JMenuItem(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_SALIR), KeyEvent.VK_S);
		mniSalir.addActionListener(miHandler);
		mnuArchivo.add(mniSalir);

		// Control de entrada

		mnuEntrada = new JMenu(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNU_ENTRADA));
		mnuEntrada.setVisible(false);
		mnbDesktop.add(mnuEntrada);

		mniEntradaSalida = new JMenuItem(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_ENTRADA_SALIDA));
		mniEntradaSalida.setVisible(false);
		mniEntradaSalida.addActionListener(miHandler);
		mnuEntrada.add(mniEntradaSalida);

		// Administracion

		mnuAdministracion = new JMenu(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNU_ADMINISTRACION));
		mnuAdministracion.setVisible(false);
		mnbDesktop.add(mnuAdministracion);

		mniUsuario = new JMenuItem(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_USUARIO));
		mniUsuario.setVisible(false);
		mniUsuario.addActionListener(miHandler);
		mnuAdministracion.add(mniUsuario);

		mniTarjeta = new JMenuItem(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_TARJETA));
		mniTarjeta.setVisible(false);
		mniTarjeta.addActionListener(miHandler);
		mnuAdministracion.add(mniTarjeta);

		mniCatalogos = new JMenuItem(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_CATALOGOS));
		mniCatalogos.setVisible(false);
		mniCatalogos.addActionListener(miHandler);
		mnuAdministracion.add(mniCatalogos);

		// EdoCta

		mnuEdoCta = new JMenu(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNU_EDOCTA));
		mnuEdoCta.setVisible(false);
		mnbDesktop.add(mnuEdoCta);

		mniAdeudo = new JMenuItem(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_ADEUDOS));
		mniAdeudo.setVisible(false);
		mniAdeudo.addActionListener(miHandler);
		mnuEdoCta.add(mniAdeudo);

		mniAbono = new JMenuItem(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_ABONOS));
		mniAbono.setVisible(false);
		mniAbono.addActionListener(miHandler);
		mnuEdoCta.add(mniAbono);

		// Preferencias

		mnuPreferencias = new JMenu(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNU_PREFERENCIAS));
		mnbDesktop.add(mnuPreferencias);

		mniAcercaDe = new JMenuItem(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_ACERCA_DE),
				KeyEvent.VK_A);
		mniAcercaDe.addActionListener(miHandler);
		mnuPreferencias.add(mniAcercaDe);

		mnuPreferencias.add(new JSeparator());
		mnuIdioma = new JMenu(mi
				.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_IDIOMA));
		JRadioButtonMenuItem tmp;
		for (Idioma i : Idioma.getIdiomas()) {
			tmp = new JRadioButtonMenuItem(i.getDescripcion(), i.equals(mi
					.getIdioma()));
			tmp.addActionListener(miHandler);
			grupoIdiomas.add(tmp);
			mnuIdioma.add(tmp);
		}
		mnuPreferencias.add(mnuIdioma);

		add(mnbDesktop);
	}

	/**
	 * Clase creada para el manejo de todas las acciones del menu
	 * 
	 * @author Victor J Morales R
	 * 
	 */
	private class MenuItemHandler implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			Object o = e.getSource();
			if (o instanceof JRadioButtonMenuItem) {
				JRadioButtonMenuItem tmp = (JRadioButtonMenuItem) o;
				Idioma seleccionado = Idioma.getIdioma(tmp.getText());
				if (ManejadorIdiomas.getInstance().getIdioma() != seleccionado) {
					ManejadorIdiomas.getInstance().setIdioma(seleccionado);
				}
			} else if (o instanceof JMenuItem) {
				if (o == mniSalir) {
					AvDesktop.getInstance().dispose();
				} else if (o == mniLogin) {
					if (as.getSesionActiva() != null) {
						cerrarSesion();
					}
					LoginFrame.getInstance().setVisible(true);
				} else if (o == mniUsuario) {
					UsuarioFrame uf = new UsuarioFrame();
					AvDesktop.getInstance().addDesktop(uf);
					uf.setVisible(true);
				} else if (o == mniTarjeta) {
					TarjetaFrame tf = new TarjetaFrame();
					AvDesktop.getInstance().addDesktop(tf);
					tf.setVisible(true);
				} else if (o == mniCatalogos) {
					ElementoCatalogoFrame ec = new ElementoCatalogoFrame();
					AvDesktop.getInstance().addDesktop(ec);
					ec.setVisible(true);
				} else if (o == mniAdeudo) {
					AdeudoFrame af = new AdeudoFrame();
					AvDesktop.getInstance().addDesktop(af);
					af.setVisible(true);
				} else if (o == mniAbono) {
					AbonoFrame abf = new AbonoFrame();
					AvDesktop.getInstance().addDesktop(abf);
					abf.setVisible(true);
				} else if (o == mniEntradaSalida) {
					EntradaSalidaFrame esf = new EntradaSalidaFrame();
					AvDesktop.getInstance().addDesktop(esf);
					esf.setVisible(true);
				}
			}
		}
	}// MenuItemHandler

	private void cerrarSesion() {
		as.setSesionActiva(null);
		mniLogin.setText(mi.obtenerEtiqueta(Etiqueta.AV_DESKTOP_MNI_LOGIN));
		cargarPermisos(Rol.DEFAULT);
	}// cerrarSesion

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		JFrame frame = new JFrame("Testing");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		MainMenuPanel mmp = new MainMenuPanel();
		mmp.cargarPermisos(Rol.ADMIN);
		frame.add(mmp);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
		frame.pack();
	}// main

}// MainMenuPanel